import type { Metadata } from 'next'; import Link from 'next/link'; import { notFound } from 'next/navigation'; import { eq } from '@/lib/db'; import { db, userBadges } from '@/lib/db'; import { publicProfile } from '@/lib/account/queries'; import { summarizePortfolio } from '@/lib/account/portfolio'; import { BADGE_DEFS } from '@/lib/account/badges'; import { Card, CardHeader, Badge, EmptyState, Delta } from '@/components/ui/primitives'; import { Donut } from '@/components/account/charts'; import { fmtMoney, fmtDate } from '@/lib/format'; export async function generateMetadata({ params }: { params: Promise<{ handle: string }> }): Promise { const { handle } = await params; const p = await publicProfile(handle); if (!p) return { title: 'Collector not found' }; const name = p.user.name ?? `@${p.user.handle}`; return { title: `${name} · Collector profile`, description: p.user.bio ?? `${name} on RareIndex`, openGraph: { title: `${name} on RareIndex`, description: p.user.bio ?? 'Collector profile', images: [`/u/${handle}/opengraph-image`] } }; } export default async function ProfilePage({ params }: { params: Promise<{ handle: string }> }) { const { handle } = await params; const p = await publicProfile(handle); if (!p) notFound(); const total = summarizePortfolio(p.items); const badges = await db().select().from(userBadges).where(eq(userBadges.userId, p.user.id)); return (
{p.user.avatarUrl ? ( // eslint-disable-next-line @next/next/no-img-element ) : ( {(p.user.name ?? p.user.handle ?? '?').slice(0, 1).toUpperCase()} )}

{p.user.name ?? `@${p.user.handle}`}

@{p.user.handle} · member since {fmtDate(p.user.createdAt, { month: 'long' })}

{p.user.bio ?

{p.user.bio}

: null} {badges.length ? (
{badges.map((b) => ( {BADGE_DEFS[b.badge]?.label ?? b.badge} ))}
) : null}

Public collection value

{total.valuedCount ? fmtMoney(total.valueUsd) : '—'}

{total.itemCount} item{total.itemCount === 1 ? '' : 's'} across {p.collections.length} public collection{p.collections.length === 1 ? '' : 's'}

{p.collections.length === 0 ? ( ) : (
{p.collections.map(({ collection: c, summary: s }) => (

{c.name}

{c.description ?? `${s.itemCount} items`}

{s.valuedCount ? fmtMoney(s.valueUsd) : '—'}

))}
({ label: b.label, value: b.valueUsd }))} size={110} />
)}

Values are RareIndex Valuation estimates with confidence levels; purchase prices are never shown publicly. RareIndex does not authenticate items.

); }